#include<iostream>
using namespace std;

// class A
// {
// public:
//     A(int x)
//     {
//         _a = x;
//     }
// private:
//     int _a;
// };

// class B
// {
// public:
//     B()
//         :_aa(1)
//         , _b(5)
//     {}

// private:
//     A _aa; 
//     int _b;
// };

// int main()
// {
//     B b;
//     return 0;
// }
// // 编译器生成的构造函数会调用A的默认构造初始化_aa


// static int _b; // static成员必须在类外面初始化

// class T
// {
//     int _t;
// public:
//     T(int x)
//     {
//         _t = x;
//     }
// };

// class A
// {
//     const int _a; 
//     int& _ref;
//     T _tt;
// public:
//     A(int& rr)
//         :_a(1)      // const / 引用 / 没有默认构造的自定义类型 必须在初始化列表初始化
//         ,_ref(rr)
//         ,_tt(2)
//     {
//         _ref = rr; // 函数体内并非初始化，而是赋值
//     }
// };

// class T
// {
//     int _t;
// public:
//     T(int x = 1)
//     {
//         _t = x;
//     }
// };

// class A
// {
//     T _tt;
//     const int _a = 1; 
// public:
//     A()
//     {}
// };

// class A
// {
//     int _a2;
//     int _a1;
// public:
//     A(int a)
//         :_a1(a)
//         ,_a2(_a1)
//         {}
//     void Print()
//     {
//         cout << _a1 << ' ' << _a2 << endl;
//     }
// };

// class A
// {
//     int _a;
// public:
//     explicit A(int x)
//         :_a(x)
//     {
//         cout << "A(int x)" << endl;
//     }

//     A (const A& a)
//         :_a(a._a)
//     {
//         cout << "A (const A& a)" << endl;
//     }
// };

// int main()
// {
//     // int n;
//     // // A a1(1);    // 构造
//     // // A a2 = a1;  // 拷贝构造

//     // // 下面是隐式类型转换
//     A a3 = 1;   
//     // // 你可以理解为下面代码：
//     // // const A tmp(1);
//     // // A a3 = tmp;

//     // // int& x = 3.3;
//     // const int& x = 3.3;

//     // // A& a = 1;
//     // const A& a = 1;
//     return 0;
// }


// class Stack
// {
//     // ... 省略成员变量
// public:
//     void Push(const A& a) // 插入的类型是A
//     {
//         // ...
//     }
//     // ... 省略其他内容
// };

// int main()
// {
//     Stack st;
//     // 如果要插入A类型变量，按理说应该写成下面：
//     A a(2);
//     st.Push(a);

//     // 有了隐式类型转换后可以直接写出：
//     st.Push(2);
//     return 0;
// }



// class A
// {
//     int _a;
//     int _a1;
//     int _a2;
// public:
//     explicit A(int x)
//         :_a(x)
//     {
//         cout << "A(int x)" << endl;
//     }

//     explicit A(int a1, int a2)
//         :_a(0)
//         ,_a1(a1)
//         ,_a2(a2)
//     {
//         cout << "A(int a1, int a2)" << endl;
//     }

//     A (const A& a)
//         :_a(a._a)
//     {
//         cout << "A (const A& a)" << endl;
//     }
// };

// int main()
// {
//     // 调用单参数构造
//     // A a(1);
//     A a1 = 1; // 隐式类型转换

//     // 调用多参数构造
//     // A aa(1, 2);
//     A aa1 = {1, 2}; // 隐式类型转换
//     // A a = (1, 2); 后面的会识别成逗号表达式，等价于 A a = 2;

//     // // C++11后，可以省略赋值符号，统一用 {}
//     // A b1 {1};       // 等价于 A b1 = 1;
//     // A b2 {1, 2};    // 等价于A b2 = {1, 2};
//     return 0;
// }


// int main()
// {
//     int a = 3.3; // a是int，3.3是double。编译器会先把3.3转换成int放在临时变量中，然后再拷贝给a
//     /*代码等价于：
//     const int tmp = 3.3;
//     int a = tmp;
//     */

//     // int& a1 = 3.3; // 临时变量具有常性，会权限放大
//     const int& a1 = 3.3;
//     return 0;
// }


////////// static

// class A
// {
//     int _a1 = 1;        // 非静态成员，使用默认成员初始化器，每个对象都有自己的拷贝
//     int _a2 = 2;        // 同上
//     static int _s;      // 静态成员变量声明
// public:
//     static int Get_s()
//     {
//         cout << _a1 << ' ' << _a2 << endl;
//         return _s;
//     }
// };

// // 静态成员的定义
// int A::_s = 0;

// int main()
// {
//     // A a;
//     // cout << A::Get_s() << endl;
//     // cout << a.Get_s() << endl;
//     return 0;
// }

// class A
// {
//     int _a1 = 1;
//     int _a2 = 2;
//     static int _s; // err
// public:

//     A() { ++_s ;}
//     A(const A& a) { ++_s; }
//     // ~A() {--_s; }
// };
// class A
// {
//     int _a1 = 1;
//     int _a2 = 2;
//     static int _s;
// };
// int A::_s = 0;

// A func()
// {
//     A a;
//     return a;
// }
// int main()
// {
//     A a1;
//     A a2;
//     A a3(a1);
//     func();
//     cout << A::_s << endl;    
//     return 0;
// }


// class A
// {
//     int _a = 10;
//     friend class B; // B 是 A 的朋友
// };

// class B
// {
//     int _b = 11;
//     friend class C;
// };

// class C
// {
//     int _c = 12;
// public:
//     void func(B b, A a)
//     {
//         cout << b._b << endl;
//         cout << a._a << endl; // 
//     }
// };

// int main()
// {
//     A a;
//     B b;

//     C c;
//     c.func(b, a);
//     return 0;
// }

// class A
// {
//     int _a;
//     int _a1;
//     int _a2;
// public:
// // 禁止隐式类型转换
//     explicit A(int x)
//         :_a(x)
//     {
//         cout << "A(int x)" << endl;
//     }
    
// // 禁止隐式类型转换
//     explicit A(int a1, int a2)
//         :_a(0)
//         ,_a1(a1)
//         ,_a2(a2)
//     {
//         cout << "A(int a1, int a2)" << endl;
//     }
// };

// int main()
// {
//     A a1 = 1; // err
//     A aa1 = {1, 2}; // err
//     return 0;
// }


// class A
// {
//     int _a = 1000;
// public:
//     void Print() { cout << _a << endl; }
//     friend class B; // A 把 B 当朋友
// };

// class B
// {
//     int _b;
// public:
//     void func(A _A)
//     {
//         cout << _A._a << endl; // A类里的_a是私有
//         // B 是 A 的朋友，B里面的成员函数都可以是A类的友元函数，都可以访问A类型对象的私有成员
//     }
// };

// int main()
// {
//     A a;
//     B b;
//     b.func(a);
//     return 0;
// }

// class A
// {
//     int _a;
// public:
//     class B // B天生就是A的友元
//     {
//         int _b;
//     public:
//         B(int x = 1)
//             :_b(x)
//         {}
//     };
// };

// int main()
// {
//     cout << sizeof(A) << endl;
//     A a;
//     A::B b; // 用B类创建对象
//     return 0;
// }

// class A
// {
//     int _a;
// public:
//     A(int x = 1)
//         :_a(x)
//     {
//         cout << "A()" << endl;
//     }
//     A(const A& a)
//     {
//         cout << "A(const A& a)" << endl;
//     }
//     ~A()
//     {
//         cout << "~A()" << endl;
//     }
//     void Print()
//     {
//         cout << _a << endl;
//     }
// };

// void func(A a)
// {
//     ;
// }

// A func()
// {
//     A a;
//     return a;
// }
// int main()
// {
//     // A a;
//     // func(a);    // 普通对象传参
//     // func(A(2)); // 匿名对象传参
//     // func(2);    // 隐式类型转换

//     A r = func();
//     const A& r1 = func();
//     return 0;
// }

class A
{
    int _a;
public:
    A()
    {
        cout << "A()" << endl;
    }
    ~A() { cout << "~A()" << endl; }
};


void func()
{
    static A a2;
}

A a1;

int main()
{
    func();
    cout << "-------------" << endl;
    func();
    cout << "-------------" << endl;
    return 0;
}